-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of the canopy model #288
Conversation
…py model implementation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #288 +/- ##
===========================================
+ Coverage 95.29% 95.54% +0.25%
===========================================
Files 28 34 +6
Lines 1720 2243 +523
===========================================
+ Hits 1639 2143 +504
- Misses 81 100 +19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this is a well-structured and thoroughly documented piece of scientific code. The use of numpy, type hinting, and input validation contributes to its robustness. My suggestions are for further improvement of the code, but not critical.
raise ValueError("Invalid shape for the z value.") | ||
|
||
|
||
def calculate_relative_canopy_radius_at_z( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the inputs array can be reshaped to be broadcastable, then using numpy functions instead of python built-ins e.g. np.power
instead of **
can help with vectorization and improve performance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to think about (and document) what shapes are sensible here. I believe that M**n
is faster if n
is a scalar but np.power(M, n)
is faster when n
is an array? Could get either in using this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think np.power will be faster if you are applying the operation to an array even if the exponent is a scaler. And you can further performance gains if you can apply np.vectorize to functions. Though I feel like I need to back up this with some testing!
I should add that I am happy to defer to James and Marion in terms of what they consider to important changes to make as they have better code and project knowledge than me. |
… 288_292_merge_prep_work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't had a in depth look at the tests yet, but generally this looks OK.
It'd be good to get some thoughts on the potential type inconsistencies for m,n and q_m in canopy_functions.py.
I would prefer to see canopy.py refactored to move the evaluations out of the constructor.
Approving review of early WIP version - needs approval of current proposed final version
@j-emberton The I guess the danger is that users might (not unreasonably) stick the |
Yeah, I see. I think I was being a bit overzealous here, and got into a mindset where those type inconsistencies in |
…tter exception messages; partial update tests
@j-emberton I think with that update to the |
👼 🤔 😈 will go ahead and approve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes
Description
[Updated to move from WIP to ready to merge].
This PR is to review, adapt and merge in @AmyOctoCat's code on the canopy object from #231.
The main areas of change from that PR are:
t_model_functions
andcanopy_functions
modules have now settled down to which functions belong in whichmodule.
canopy_functions
module has now been extended to include the canopy vertical structure functions from WIP - 230 create a draft canopy class #231, including the relative canopy radius, stem crown area and stem leaf area at given heights, along with a solver function to find the height at which a canopy layer closes. This includes:Community
object as an argument within thecanopy_functions
functions and replacing it with explicit arguments for the community properties for each function. This makes the core functions more flexible.Canopy
object has been reworked to use this new functionality to get to the same end point as in WIP - 230 create a draft canopy class #231.In addition, from the earlier WIP version of the PR, this code:
pandas
data structure in favour of simple use ofnumpy
arrays throughout (see Replace use ofpandas
inpyrealm.demography
#292).t_model_functions
to include validation of the input argument shapes and then builds out a deeper unit test suite to a range of input combinations using predictions from the original R implementation.Things to do later:
canopy.md
document to use this code.Canopy
object to use it to generate absorbed radiation per stem per layer and hence generate productivity estimates.Fixes #286 (issue)
Type of change
Key checklist
pre-commit
checks:$ pre-commit run -a
$ poetry run pytest
Further checks